﻿using System;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.Text;
using Ch.Admin.Bfs.Sms.Sdmx.Extension.CodeBook.Meta;

namespace Ch.Admin.Bfs.Sms.Sdmx.Extension.CodeBook.Pdf
{
    public class CatalogHierarchy
    {
        private bool hasNumbering;

        private bool isAlternateRow;
        private bool isTypeShown;

        private string fullIdKey;

        /// <summary>Metadata provider</summary>
        protected IMetaProvider metaProvider;

        /// <summary>All different fonts used</summary>
        protected PdfFonts BookFonts;

        /// <summary>ITextSharp document worker </summary>
        protected Document doc;

        public PdfPTable Table { get; private set; }

        /// <summary>
        /// Total width allowed to a table
        /// </summary>
        protected float TotalWidth
        {
            get
            {
                return doc.PageSize.Width - doc.LeftMargin - doc.RightMargin;
            }
        }


        public CatalogHierarchy(IMetaProvider mp, bool numbering, bool showType, PdfFonts fonts, Document pdfDocument)
        {
            metaProvider = mp;
            fullIdKey = metaProvider.FullIdKey;
            isTypeShown = showType;
            hasNumbering = numbering;
            doc = pdfDocument;
            BookFonts = fonts;

            CreateTable();
            CreateTitle();

        }

        private void CreateTable()
        {
            Table = new PdfPTable(3);
            float[] widths = new float[] { 10f, 75f, 15f };
            Table.SetWidths(widths);
            Table.TotalWidth = TotalWidth;
        }

        private void CreateTitle()
        {
            Phrase ph = new Phrase("Tableau récapitulatif des variables du module", BookFonts.FontLevelOne);
            PdfPCell cell = new PdfPCell(ph);
            cell.Border = Rectangle.LEFT_BORDER;
            cell.BorderColor = BaseColor.WHITE;
            cell.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_HEAD);
            cell.PaddingBottom = 6f;
            cell.VerticalAlignment = Element.ALIGN_MIDDLE;
            cell.Colspan = 3;
            Table.AddCell(cell);
        }


        private void CreateTitle2()
        {
            Phrase ph = new Phrase(" ID: Name", BookFonts.FontTableHead);
            PdfPCell cell = new PdfPCell(ph);
            cell.Border = Rectangle.LEFT_BORDER;
            cell.BorderColor = BaseColor.WHITE;
            cell.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_GREY);
            cell.PaddingBottom = 3f;
            cell.VerticalAlignment = Element.ALIGN_MIDDLE;


            if (hasNumbering)
            {
                cell.Colspan = (isTypeShown) ? 1 : 2;
                Phrase phno = new Phrase("No", BookFonts.FontTableHead);
                PdfPCell cellno = new PdfPCell(phno);
                cellno.Border = Rectangle.LEFT_BORDER;
                cellno.BorderColor = BaseColor.WHITE;
                cellno.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_GREY);
                cellno.PaddingBottom = 3f;
                cell.PaddingLeft = 3f;
                cellno.VerticalAlignment = Element.ALIGN_MIDDLE;
                Table.AddCell(cellno);
                Table.AddCell(cell);

            }
            else
            {
                cell.Colspan = (isTypeShown) ? 2 : 3;
                Table.AddCell(cell);
            }

            if (isTypeShown)
            {
                Phrase phType = new Phrase("Type", BookFonts.FontTableHead);
                PdfPCell cellType = new PdfPCell(phType);
                cellType.Border = Rectangle.LEFT_BORDER;
                cellType.BorderColor = BaseColor.WHITE;
                cellType.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_GREY);
                cellType.PaddingBottom = 3f;
                cellType.VerticalAlignment = Element.ALIGN_MIDDLE;
                Table.AddCell(cellType);

            }

        }

        private string AddRow(string parentlevelId, int level, int index, string text, string anchorReference, string varType)
        {
            string levelId = string.IsNullOrEmpty(parentlevelId) ? index.ToString() : parentlevelId + "." + index.ToString();
            
            Phrase ph = new Phrase(text, BookFonts.FontStandard);
            PdfPCell cell = new PdfPCell(ph);
            if (string.IsNullOrEmpty(anchorReference) == false)
            {
                Anchor click = new Anchor(ph);
                click.Reference = anchorReference;
                cell = new PdfPCell(click);
            }
            cell.Border = Rectangle.LEFT_BORDER;
            cell.BorderColor = BaseColor.WHITE;
            if (isAlternateRow)
                cell.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_ALTERNED);
            cell.VerticalAlignment = Element.ALIGN_MIDDLE;
            cell.PaddingBottom = 3f;
            cell.PaddingLeft = 3f + 10f * level;

            if (hasNumbering)
            {
                cell.Colspan = (isTypeShown) ? 1 : 2;
                Phrase phno = new Phrase(levelId, BookFonts.FontStandard);
                PdfPCell cellno = new PdfPCell(phno);
                cellno.Border = Rectangle.LEFT_BORDER;
                cellno.BorderColor = BaseColor.WHITE;
                if (isAlternateRow)
                    cellno.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_ALTERNED);
                cellno.PaddingBottom = 3f;
                cellno.VerticalAlignment = Element.ALIGN_MIDDLE;
                Table.AddCell(cellno);
                Table.AddCell(cell);
            }
            else
            {
                cell.Colspan = (isTypeShown) ? 2 : 3;
                Table.AddCell(cell);
            }

            if (isTypeShown)
            {
                Phrase phType = new Phrase(varType, BookFonts.FontStandard);
                PdfPCell cellType = new PdfPCell(phType);
                cellType.Border = Rectangle.LEFT_BORDER;
                cellType.BorderColor = BaseColor.WHITE;
                if (isAlternateRow)
                    cellType.BackgroundColor = new BaseColor(BookFonts.COLOR_TABLE_ALTERNED);
                cellType.PaddingBottom = 3f;
                cellType.VerticalAlignment = Element.ALIGN_MIDDLE;
                Table.AddCell(cellType);
            }

            isAlternateRow = !isAlternateRow;
            return levelId;
        }

        public void FillTable(HierarchyNode parentHierarchyNode)
        {
            int index = 0;
            foreach (HierarchyNode childNode in parentHierarchyNode.Nodes)
                AddRecurse(childNode, string.Empty, 0, ++index);

        }


        public static bool HasSubConceptFlag(HierarchyNode node)
        {
            bool sub = false;
            if (node.Nodes != null && node.Nodes.Count == 1)
            {
                string childId = node.Nodes[0].Id;
                if (childId.EndsWith("_F") && childId.Substring(0, childId.Length - 2) == node.Id)
                    sub = true;
            }
                
            return sub;
        }


        private void AddRecurse(HierarchyNode node, string parentlevelId, int level, int index)
        {


            string text = string.Format("{0}: {1}", node.Id, node.Name);
            string target = "#" + fullIdKey + node.Id;
            string curLevelId = AddRow(parentlevelId, level, index, text, target, metaProvider.GetVariableType(node));
            int subIndex = 0;

            // Sub concept flag are not listed
            if (HasSubConceptFlag(node) == false)
                foreach (HierarchyNode childNode in node.Nodes)
                    AddRecurse(childNode, curLevelId, level + 1, ++subIndex);

        }





    }
}
